package qeug.shsh.bpm.service.impl;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import com.bes.enterprise.logging.internal.Log;
import com.bes.enterprise.logging.internal.LogFactory;
import com.bes.mq.org.apache.commons.codec.digest.DigestUtils;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.data.idi.data.attachment.CheckMethodEnum;
import kd.data.idi.engine.attachment.Attachment;
import kd.data.idi.engine.attachment.AttachmentServiceFactory;
import qeug.shsh.bpm.annotation.ThridSrevice;
import qeug.shsh.bpm.domain.*;
import qeug.shsh.bpm.service.BPMSreviceV2;
import qeug.shsh.bpm.utils.BPMUtil;
import qeug.shsh.facde.controller.SupplierController;
import qeug.shsh.helper.FacadeHelper;

import javax.xml.rpc.ServiceException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @projectName: qeug-cosmic-root-project
 * @package: qeug.shsh.bpm.service.impl
 * @className: BPMServicelmplV2
 * @author: xuhh
 * @description: TODO
 * @date: 2025/1/13 16:08
 * @version: 1.0
 * 说明：新推送BPM接口，推送单据未：付款申请单，借款单，资金计划和资金计划调整
 */
@ThridSrevice("BPMServiceImplV2")
public class BPMServiceImplV2 implements BPMSreviceV2 {

    private final static Log logger = LogFactory.getLog(BPMServiceImplV2.class);//日志

    //付款申请单
    @Override
    public void publicReimburseBill(DynamicObject er_publicReimburseBill) throws ServiceException, RemoteException, MalformedURLException {

        String bpmv2_url = System.getProperty("bpmv2.url");
        String basicAuthUserName = System.getProperty("bpmv2.user");//名字
        String basicAuthPassword = System.getProperty("bpmv2.password");//密钥
        String returnUrl = System.getProperty("bpm.returnUrl");//URL地址
        String domain = System.getProperty("domain.contextUrl");//IP地址

        //日志
        HashMap<String, Object> log = new HashMap<>();
        log.put("operationModule", "付款申请单");
        log.put("url", bpmv2_url);
        log.put("user", basicAuthUserName);
        log.put("mode", "POST");
        log.put("action", "");
        log.put("opdate", new Date());
        BpmApplyInfo bpmApplyInfo = new BpmApplyInfo();
        ArrayList<FtEntry> ftEntrys = new ArrayList<>();//分摊明细
        ArrayList<FyEntry> fyEntrys = new ArrayList<>();//费用分录
        ArrayList<SkEntry> skEntrys = new ArrayList<>();//收款分录
        ArrayList<InvoiceEntrys> InvoiceEntrys = new ArrayList<>();//发票分录
        List<Attentrys> attEntrys = new ArrayList<Attentrys>();//附件分录
        String number = er_publicReimburseBill.getString("billno");//单据编码
        DynamicObject applier = er_publicReimburseBill.getDynamicObject("applier");//申请人
        if (applier != null) {
            String userNumber = applier.getString("number");
            String userName = applier.getString("name");
            bpmApplyInfo.setApplierNumber(userNumber);
            bpmApplyInfo.setApplierName(userName);
        }
        DynamicObject org = er_publicReimburseBill.getDynamicObject("org");//申请部门
        if (org != null) {
            String orgNumber = org.getString("number");
            String orgName = org.getString("name");
            bpmApplyInfo.setAdminOrgNumber(orgNumber);
            bpmApplyInfo.setAdminOrgName(orgName);
        }
        DynamicObject company = er_publicReimburseBill.getDynamicObject("company");//申请公司
        if (company != null) {
            String companyNumber = company.getString("number");
            String companyName = company.getString("name");
            bpmApplyInfo.setCompanyNumber(companyNumber);
            bpmApplyInfo.setCompanyName(companyName);
        }
        DynamicObject paycompany = er_publicReimburseBill.getDynamicObject("paycompany");//支付公司
        if (paycompany != null) {
            String payCompanyName = paycompany.getString("name");
            bpmApplyInfo.setPayingName(payCompanyName);
        }
        Date applyDate = er_publicReimburseBill.getDate("bizdate");//申请日期
        DynamicObject costDept = er_publicReimburseBill.getDynamicObject("qeug_costdept");//一级承担部门
        if (costDept != null) {
            String costDeptNumber = costDept.getString("number");
            String costDeptName = costDept.getString("name");
            bpmApplyInfo.setExpenseDeptCode(costDeptNumber);
            bpmApplyInfo.setExpenseDeptName(costDeptName);
        }
        DynamicObject costCompany = er_publicReimburseBill.getDynamicObject("costcompany");//费用承担公司
        if (costCompany != null) {
            String costCompanyNumber = costCompany.getString("number");
            String costCompanyName = costCompany.getString("name");
            bpmApplyInfo.setCostBearingCode(costCompanyNumber);
            bpmApplyInfo.setCostBearingName(costCompanyName);
        }
        String billPayerType = er_publicReimburseBill.getString("billpayertype");//往来类型
        if ("bd_supplier".equals(billPayerType)) {
            bpmApplyInfo.setTransactionType("供应商");
        } else if ("bd_customer".equals(billPayerType)) {
            bpmApplyInfo.setTransactionType("客户");
        } else if ("bos_user".equals(billPayerType)) {
            bpmApplyInfo.setTransactionType("职员");
        }
        DynamicObject billPayerId = er_publicReimburseBill.getDynamicObject("billpayerid");//往来单位
        if (billPayerId != null) {
            String billPayerIdName = billPayerId.getString("name");
            bpmApplyInfo.setBillPayerId(billPayerIdName);
        }
        DynamicObject travelCostcEnter = er_publicReimburseBill.getDynamicObject("std_costcenter");//成本中心
        if (travelCostcEnter != null) {
            String travelCostcEnterName = travelCostcEnter.getString("name");
            String travelCostcEnterNumber = travelCostcEnter.getString("number");
            bpmApplyInfo.setCostCenterName(travelCostcEnterName);
            bpmApplyInfo.setCostCenterCode(travelCostcEnterNumber);
        }
        boolean isCurrency = er_publicReimburseBill.getBoolean("iscurrency");//多币别
        if (isCurrency) {
            bpmApplyInfo.setisCurrency("是");
        } else {
            bpmApplyInfo.setisCurrency("否");
        }
        String insideCause = er_publicReimburseBill.getString("description");//事由（内）
        //付款信息面板：
        String fundPlanEntry = er_publicReimburseBill.getString("qeug_fundplanentry");//资金计划行号
        String isFundPlanReferenced = er_publicReimburseBill.getString("qeug_budgettype");//是否引用资金计划
        isFundPlanReferenced = "0".equals(isFundPlanReferenced) ? "否" : "是";
        String paymentType = er_publicReimburseBill.getString("qeug_paytype");//付款类别
        if ("1".equals(paymentType)) {
            paymentType = "应付";
        } else if ("2".equals(paymentType)) {
            paymentType = "预付";
        } else if ("3".equals(paymentType)) {
            paymentType = "事项";
        }
        String budgetType = er_publicReimburseBill.getString("qeug_budgetflag");//预算类型
        if ("0".equals(budgetType)) {
            budgetType = "预算外";
        } else if ("1".equals(budgetType)) {
            budgetType = "预算内";
        }
        bpmApplyInfo.setIsCyu(budgetType);
        String qeug_combofield = er_publicReimburseBill.getString("qeug_combofield");//标准内外
        if ("0".equals(qeug_combofield)) {
            qeug_combofield = "标准外";
        } else if ("1".equals(qeug_combofield)) {
            qeug_combofield = "标准内";
        }
        bpmApplyInfo.setIsCb(qeug_combofield);
        String planType = er_publicReimburseBill.getString("qeug_plantype");//计划类型
        if ("0".equals(planType)) {
            planType = "银行存款";
        } else if ("1".equals(planType)) {
            planType = "承兑汇票";
        } else if ("2".equals(planType)) {
            planType = "信用证";
        }
        DynamicObject settlementMethod = er_publicReimburseBill.getDynamicObject("qeug_settlementtype");//结算方式
        if (settlementMethod != null) {
            String settlementTypeName = settlementMethod.getString("name");
            bpmApplyInfo.setSettlementMethod(settlementTypeName);
        }
        String approvalCategoryDesc = er_publicReimburseBill.getString("qeug_descriptions");//审批类别-具体描述
        String approvalCategoryProject = er_publicReimburseBill.getString("qeug_project");//审批类别-项目
        DynamicObject approvalCategory = er_publicReimburseBill.getDynamicObject("qeug_approvaltype");//审批类别
        if (approvalCategory != null) {
            String approvalCategoryName = approvalCategory.getString("name");
            bpmApplyInfo.setApprovalCategory(approvalCategoryName);
        }
        String paymentMethod = er_publicReimburseBill.getString("qeug_patternpayment");//支付方式
        if ("0".equals(paymentMethod)) {
            paymentMethod = "汇款";
        } else if ("1".equals(paymentMethod)) {
            paymentMethod = "柜台付款";
        } else if ("2".equals(paymentMethod)) {
            paymentMethod = "转存";
        } else if ("3".equals(paymentMethod)) {
            paymentMethod = "扣款";
        }
        DynamicObject fundCategory = er_publicReimburseBill.getDynamicObject("qeug_fundtype");//资金类别
        if (fundCategory != null) {
            String fundCategoryName = fundCategory.getString("name");
            bpmApplyInfo.setFundCategory(fundCategoryName);
        }
        DynamicObject largePaymentCategory = er_publicReimburseBill.getDynamicObject("qeug_categoryl");//款项大类
        if (largePaymentCategory != null) {
            String largePaymentCategoryName = largePaymentCategory.getString("name");
            bpmApplyInfo.setLargePaymentCategory(largePaymentCategoryName);
        }
        DynamicObject paymentPurpose = er_publicReimburseBill.getDynamicObject("qeug_usefunds");//款项用途
        if (paymentPurpose != null) {
            String paymentPurposeName = paymentPurpose.getString("name");
            bpmApplyInfo.setPaymentPurpose(paymentPurposeName);
        }
        BigDecimal amountPayable = er_publicReimburseBill.getBigDecimal("qeug_amountpayable");//应付金额
        BigDecimal deductionAmount = er_publicReimburseBill.getBigDecimal("qeug_deduction");//扣款金额
        BigDecimal actualPaymentAmount = er_publicReimburseBill.getBigDecimal("qeug_amount");//实付金额
        String contractNumber = er_publicReimburseBill.getString("qeug_contractnum");//合同号
        DynamicObject salesperson = er_publicReimburseBill.getDynamicObject("qeug_salesman");//业务员
        if (salesperson != null) {
            String salespersonName = salesperson.getString("name");
            String salespersonNumber = salesperson.getString("number");
            bpmApplyInfo.setSalesmanName(salespersonName);
            bpmApplyInfo.setSalesmanNumber(salespersonNumber);
        }
        DynamicObject qeug_profitcentervalue = er_publicReimburseBill.getDynamicObject("qeug_profitcentervalue");//利润中心
        if (qeug_profitcentervalue != null) {
            String profitCenter = qeug_profitcentervalue.getString("name");
            bpmApplyInfo.setProfitCenter(profitCenter);
        }
        DynamicObject qeug_ccrange = er_publicReimburseBill.getDynamicObject("qeug_ccrange");//信贷控制范围
        if (qeug_ccrange != null) {
            String scocrControl = qeug_ccrange.getString("name");
            bpmApplyInfo.setScocrControl(scocrControl);
        }
        String investmentProject = er_publicReimburseBill.getString("qeug_invesproject");//投资项目
        String appAmountInWords = er_publicReimburseBill.getString("qeug_camount");//本次申请表金额大写

        bpmApplyInfo.setBillType("付款申请单");
        bpmApplyInfo.setNumber(number);
        bpmApplyInfo.setBizdate(String.valueOf(applyDate));
        bpmApplyInfo.setReason(insideCause);
        bpmApplyInfo.setFundPlanRowNo(fundPlanEntry);
        bpmApplyInfo.setFundPlanRowNo(fundPlanEntry);
        bpmApplyInfo.setIsFundPlanReferenced(isFundPlanReferenced);
        bpmApplyInfo.setPaymentCategory(paymentType);
        bpmApplyInfo.setPlanType(planType);
        bpmApplyInfo.setApprovalCategoryDesc(approvalCategoryDesc);
        bpmApplyInfo.setApprovalCategoryProject(approvalCategoryProject);
        bpmApplyInfo.setPaymentMethod(paymentMethod);
        bpmApplyInfo.setAmountPayable(amountPayable);
        bpmApplyInfo.setDeductionAmount(deductionAmount);
        bpmApplyInfo.setActualPaymentAmount(actualPaymentAmount);
        bpmApplyInfo.setContractNumber(contractNumber);
        bpmApplyInfo.setInvestmentProject(investmentProject);
        bpmApplyInfo.setAppAmountInWords(appAmountInWords);

        boolean isBeforeShare = er_publicReimburseBill.getBoolean("isbeforeshare");//费用分摊
        if (isBeforeShare) {
            bpmApplyInfo.setisBeforeShare("是");
            String allocationRule = er_publicReimburseBill.getString("sharerule");//分摊规则
            if ("orgrule".equals(allocationRule)) {
                allocationRule = "按部门分摊";
            } else if ("monthrule".equals(allocationRule)) {
                allocationRule = "按月分摊";
            } else if ("yearrule".equals(allocationRule)) {
                allocationRule = "按年分摊";
            } else if ("expenseitemrule".equals(allocationRule)) {
                allocationRule = "按费用项目分摊";
            }
            String method = er_publicReimburseBill.getString("sharemethod");//分摊方法
            if ("rate".equals(method)) {
                method = "比例分摊";
            } else if ("avg".equals(method)) {
                method = "金额平均";
            } else if ("amount".equals(method)) {
                method = "金额分摊";
            }
            bpmApplyInfo.setAllocationRule(allocationRule);
            bpmApplyInfo.setMethod(method);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
            Date startingMonth = er_publicReimburseBill.getDate("sharerule_startdate");//开始月份
            Date endMonth = er_publicReimburseBill.getDate("sharerule_enddate");//结束月份
            if (startingMonth != null && endMonth != null) {
                bpmApplyInfo.setStartingMonth(dateFormat.format(startingMonth));
                bpmApplyInfo.setEndMonth(dateFormat.format(endMonth));
            }
            StringBuilder departmentsBuilder = new StringBuilder();
            //分摊明细
            DynamicObjectCollection apportionCollection = er_publicReimburseBill.getDynamicObjectCollection("expenseentryentity_rule");
            for (int i = 0; i < apportionCollection.size(); i++) {
                DynamicObject itineraryEntry = apportionCollection.get(i);
                FtEntry ftEntry = new FtEntry();
                DynamicObject ftCostCompany = itineraryEntry.getDynamicObject("entrycostcompany_orgrule");//费用承担公司
                if (ftCostCompany != null) {
                    String ftCostCompanyName = ftCostCompany.getString("name");
                    String ftCostCompanyNumber = ftCostCompany.getString("number");
                    ftEntry.setFtCostCompanyName(ftCostCompanyName);
                    ftEntry.setFtCostCompanyNumber(ftCostCompanyNumber);
                }
//                DynamicObject ftCostDept = itineraryEntry.getDynamicObject("entrycostdept_orgrule");//费用承担部门
                DynamicObject ftCostDept = itineraryEntry.getDynamicObject("qeug_costdeptrule");//一级承担部门
                if (ftCostDept != null) {
                    String ftCostDeptName = ftCostDept.getString("name");
                    String ftCostDeptNumber = ftCostDept.getString("number");
                    if (i > 0) {
                        departmentsBuilder.append(","); // 在部门编号之间添加逗号和空格
                    }
                    departmentsBuilder.append(ftCostDeptNumber);
                    ftEntry.setFtCostDeptName(ftCostDeptName);
                    ftEntry.setFtCostDeptNumber(ftCostDeptNumber);
                }

                DynamicObject std_entrycostcenter_crule = itineraryEntry.getDynamicObject("std_entrycostcenter_crule");//成本中心
                if (std_entrycostcenter_crule != null) {
                    String costCenterName = std_entrycostcenter_crule.getString("name");
                    String costCenterNumber = std_entrycostcenter_crule.getString("number");
                    ftEntry.setCostCenterName(costCenterName);
                    ftEntry.setCostCenterNumber(costCenterNumber);
                }

                String amortizationRatio = itineraryEntry.getString("sharerate_comrule");//分摊比例（%）
                String formattedRatio = String.format("%.2f", Double.valueOf(amortizationRatio));
                DynamicObject std_project_comrule = itineraryEntry.getDynamicObject("std_project_comrule");//项目
                if (std_project_comrule != null) {
                    String projectName = std_project_comrule.getString("name");
                    ftEntry.setItem(projectName);
                }
                String remark = itineraryEntry.getString("shareremark");//备注
                BigDecimal assessedAmount = itineraryEntry.getBigDecimal("shareamount_comrule");//分摊金额
                String waitingBankNumber = itineraryEntry.getString("sharewaitseq_comrule");//待摊行号
                Date month = itineraryEntry.getDate("entrymonth_monthrule");//月份
                if (month != null) {
                    ftEntry.setMonth(dateFormat.format(month));
                }

                ftEntry.setAmortizationRatio(formattedRatio);
                ftEntry.setRemark(remark);
                ftEntry.setAssessedAmount(assessedAmount);
                ftEntry.setWaitingBankNumber(waitingBankNumber);

                ftEntrys.add(ftEntry);
            }
            String departments = departmentsBuilder.toString();
            bpmApplyInfo.setDepartments(departments);//分摊部门
        } else {
            bpmApplyInfo.setDepartments("");//分摊部门,没有分摊的时候分摊部门字段传空
            bpmApplyInfo.setisBeforeShare("否");
        }
        //费用明细
        DynamicObjectCollection expenselCollection = er_publicReimburseBill.getDynamicObjectCollection("expenseentryentity");
        for (int j = 0; j < expenselCollection.size(); j++) {
            DynamicObject expenseEntry = expenselCollection.get(j);
            FyEntry fyEntry = new FyEntry();
            DynamicObject entryCostDept = expenseEntry.getDynamicObject("entrycostdept");//费用承担部门
            if (entryCostDept != null) {
                String entryCostDeptName = entryCostDept.getString("name");
                fyEntry.setExpenseDeptName(entryCostDeptName);
            }
            DynamicObject expenseType = expenseEntry.getDynamicObject("qeug_expensetype");//费用类型
            if (expenseType != null) {
                String expenseTypeName = expenseType.getString("fullname");
                fyEntry.setExpenseType(expenseTypeName);
            }
            DynamicObject expenseDetail = expenseEntry.getDynamicObject("qeug_expensedetail");//费用细项
            if (expenseDetail != null) {
                String expenseDetailName = expenseDetail.getString("fullname");
                fyEntry.setExpenseDetail(expenseDetailName);
            }
            DynamicObject expenseItem = expenseEntry.getDynamicObject("expenseitem");//费用名目（长名称，编码
            if (expenseItem != null) {
                String expenseItemName = expenseItem.getString("fullname");
                String expenseItemNumber = expenseItem.getString("number");
                fyEntry.setExpenseItemName(expenseItemName);
                fyEntry.setExpenseItemNumber(expenseItemNumber);
            }
            SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date happenDate = expenseEntry.getDate("happendate");//费用发生日期
            if (happenDate != null) {
                String parse = inputFormat.format(happenDate);// 解析为 Date 对象
                fyEntry.setHappendate(parse);
            } else {
                fyEntry.setHappendate(String.valueOf(happenDate));
            }
            BigDecimal amount = expenseEntry.getBigDecimal("expenseamount");//本次申请金额
            String remark = expenseEntry.getString("remark");//备注
            if (isCurrency) {
                DynamicObject entryCurrency = expenseEntry.getDynamicObject("entrycurrency");//币别
                String entryCurrencyName = entryCurrency.getString("name");
                fyEntry.setEntryCurrency(entryCurrencyName);
            } else {
                fyEntry.setEntryCurrency("人民币");//多币别关闭时推送人民币
            }
            String exchanGerate = expenseEntry.getString("exchangerate");//汇率
            if (exchanGerate != null) {
                exchanGerate = String.format("%.2f", Double.parseDouble(exchanGerate));
            }
            fyEntry.setExchanGerate(exchanGerate);
            BigDecimal amountRaw = expenseEntry.getBigDecimal("currexpenseamount");//本次申请金额（本位币）
            String taxRate = expenseEntry.getString("taxrate");//税率
            String taxRates = String.format("%.2f", Double.parseDouble(taxRate));
            String taxAmount = expenseEntry.getString("taxamount");//税额
            String taxAmounts = String.format("%.2f", Double.parseDouble(taxAmount));
            BigDecimal noTaxAmount = expenseEntry.getBigDecimal("orientryamount");//不含税金额
            String invoiceno = expenseEntry.getString("invoiceno_entry");//发票号码
            String commodityName = expenseEntry.getString("expensegoodsname");//商品名称

            fyEntry.setTaxrate(taxRates);
            fyEntry.setTax(taxAmounts);
            fyEntry.setAmountRaw(amountRaw);
            fyEntry.setAmount(amount);
            fyEntry.setComment(remark);
            fyEntry.setNotaxamount(noTaxAmount);
            fyEntry.setInvoiceno(invoiceno);
            fyEntry.setCommodityName(commodityName);

            fyEntrys.add(fyEntry);
        }
        //收款页签
        DynamicObjectCollection receiptCollection = er_publicReimburseBill.getDynamicObjectCollection("accountentry");
        for (int i = 0; i < receiptCollection.size(); i++) {
            DynamicObject receiptEntry = receiptCollection.get(i);
            SkEntry skEntry = new SkEntry();
            if (settlementMethod != null) {
                //取用单据头的结算方式
                String paymodeName = settlementMethod.getString("name");
                String paymodeNumber = settlementMethod.getString("number");
                skEntry.setPayTpye(paymodeName);
                skEntry.setPayTpyeNumber(paymodeNumber);
            }
            String payerType = receiptEntry.getString("payertype");//收款人类型
            if ("bd_supplier".equals(payerType)) {
                skEntry.setRecipientType("供应商");
            } else if ("bd_customer".equals(payerType)) {
                skEntry.setRecipientType("客户");
            } else if ("bos_org".equals(payerType)) {
                skEntry.setRecipientType("内部公司");
            } else if ("er_payeer".equals(payerType)) {
                skEntry.setRecipientType("个人");
            } else if ("other".equals(payerType)) {
                skEntry.setRecipientType("其他");
            }
            String payertype = receiptEntry.getString("payertype");//收款人类型
            if (payertype.equals("bd_supplier")) {
                //收款人类型为供应商
                DynamicObject payee = receiptEntry.getDynamicObject("supplier");//收款人-供应商
                String payeeName = payee.getString("name");
                String payeeNumber = payee.getString("number");
                skEntry.setPayeeName(payeeName);
                skEntry.setPayeeNumber(payeeNumber);
            } else if (payertype.equals("er_payeer")) {
                //收款人类型为人员
                DynamicObject payee = receiptEntry.getDynamicObject("payer");//收款人-人员
                String payeeName = payee.getString("name");
                String payeeNumber = payee.getString("payer.number");
                skEntry.setPayeeName(payeeName);
                skEntry.setPayeeNumber(payeeNumber);
            } else {
                //收款人类型为客户
                DynamicObject payee = receiptEntry.getDynamicObject("customer");//收款人-客户
                String payeeName = payee.getString("name");
                String payeeNumber = payee.getString("number");
                skEntry.setPayeeName(payeeName);
                skEntry.setPayeeNumber(payeeNumber);
            }
            String payeeAccount = receiptEntry.getString("payeraccount");//银行账号
            String correspondentNumber = receiptEntry.getString("qeug_union");//联行号
            String accountTitle = receiptEntry.getString("payeraccountname");//账户名称
            DynamicObject openBankAccount = receiptEntry.getDynamicObject("payerbank");//开户银行
            if (openBankAccount != null) {
                String openBankAccountName = openBankAccount.getString("name");
                String openBankAccountNumber = openBankAccount.getString("number");
                skEntry.setBankName(openBankAccountName);
                skEntry.setBankNumber(openBankAccountNumber);
            }
            BigDecimal receiveAmount = receiptEntry.getBigDecimal("orireceiveamount");//收款金额
            boolean paynow = receiptEntry.getBoolean("ispaynow");//立即支付
            if (paynow) {
                skEntry.setPaynow("是");
            } else {
                skEntry.setPaynow("否");
            }
            if (isCurrency) {
                DynamicObject entryCurrency = receiptEntry.getDynamicObject("accountcurrency");//币别
                String entryCurrencyName = entryCurrency.getString("name");
                skEntry.setEntryCurrency(entryCurrencyName);
            } else {
                skEntry.setEntryCurrency("人民币");//多币别关闭时推送人民币
            }
            String exchanGerate = receiptEntry.getString("accexchangerate");//汇率
            if (exchanGerate != null) {
                String exchanGerates = String.format("%.2f", Double.parseDouble(exchanGerate));
                skEntry.setExchanGerate(exchanGerates);
            }
            BigDecimal attachmentsRaw = receiptEntry.getBigDecimal("receiveamount");//收款金额（本位币）

            skEntry.setAttachmentsRaw(attachmentsRaw);
            skEntry.setBankNum(payeeAccount);
            skEntry.setAccountTitle(accountTitle);
            skEntry.setInterbank(correspondentNumber);
            skEntry.setAttachments(receiveAmount);

            skEntrys.add(skEntry);
        }

        //发票分录
        DynamicObjectCollection invoiceCollection = er_publicReimburseBill.getDynamicObjectCollection("invoiceentry");
        for (DynamicObject invoiceEntry : invoiceCollection) {
            InvoiceEntrys InvoiceEntry1 = new InvoiceEntrys();
            String serialNo = invoiceEntry.getString("serialno");//发票流水号
            String invoicegoodsname = invoiceEntry.getString("invoicegoodsname");//商品名称
            if (invoicegoodsname != null) {
                InvoiceEntry1.setInvoiceName(invoicegoodsname);//发票名称
            } else {
                String invoiceNo = invoiceEntry.getString("invoiceno");//发票号码
                InvoiceEntry1.setInvoiceName(invoiceNo);//发票名称
            }
            String downloadUrl = FacadeHelper.getDownloadUrl2(serialNo);
            String attUrl = domain + "/accessTokenLogin.do?access_token={}&redirect=" + downloadUrl;//推送下载地址

            InvoiceEntry1.setInvoiceUrls(attUrl);//下载地址

            InvoiceEntrys.add(InvoiceEntry1);
        }

        //附件分录
        long billId = er_publicReimburseBill.getLong("id");
        List tripReimburse = AttachmentServiceFactory.getServiceInstance(CheckMethodEnum.CUSTOM).queryAttachmentInfo(billId, "er_publicreimbursebill", false);
        for (Object attachment : tripReimburse) {
            Attentrys attEntry = new Attentrys();
            Attachment bos_attachment = (Attachment) attachment;
            String url = bos_attachment.getUrl();
            String attUrl = domain + "/accessTokenLogin.do?access_token={}&redirect=" + url;//附件地址
            String fileName = bos_attachment.getFileName();//附件名称
            String attType = bos_attachment.getFileType();//附件类型

            attEntry.setAttUrl(attUrl);
            attEntry.setAttName(fileName);
            attEntry.setAttType(attType);

            attEntrys.add(attEntry);
        }

        //人员信息
        DynamicObject creator = er_publicReimburseBill.getDynamicObject("creator");//创建人
        String creatorNumber = creator.getString("number");

        String strProcessName = "CCSFuKuanSQ";

        String summaryV2 = BPMUtil.getSummaryV2(er_publicReimburseBill);

        String combinedString = "94893e8a64a2444d8cd41237e6a8bd56" + er_publicReimburseBill.getString("billno");
        String signature = DigestUtils.md5Hex(combinedString);
        String shortSignature = signature.substring(8, 24);

        //拼接Json
        bpmApplyInfo.setAttentrys(attEntrys);
        bpmApplyInfo.setFyEntry(fyEntrys);
        bpmApplyInfo.setSkEntry(skEntrys);
        bpmApplyInfo.setFtEntry(ftEntrys);
        bpmApplyInfo.setInvoiceEntrys(InvoiceEntrys);

        bpmApplyInfo.setSysName("CCS");
        bpmApplyInfo.setDataId(er_publicReimburseBill.getString("billno"));
        bpmApplyInfo.setDataVersion("");//为空
        bpmApplyInfo.setSignature(shortSignature);
        bpmApplyInfo.setProcessName(strProcessName);
        bpmApplyInfo.setInitiatorName(creatorNumber);
        bpmApplyInfo.setReturnUrl(returnUrl);
        bpmApplyInfo.setFormUrl("");//为空
        bpmApplyInfo.setTitle(summaryV2);

        String json = JSONObject.toJSONString(bpmApplyInfo);

        String access_token = getAccessToken(bpmv2_url, basicAuthUserName, basicAuthPassword);
        String send_standard = HttpRequest.post(bpmv2_url + "/hitf/v2p/rest/invoke/SFpFUk86QlBNOkJQTV9TREsz")
                .header("Authorization", access_token)
                .body(json).execute().body();

        log.put("mainstring", json);
        log.put("responsebody", send_standard);
        logger.info("付款申请单bpm回传信息：" + send_standard);
        log.put("pdesc", "记录付款申请回传信息");
        FacadeHelper.apiLog(log);

        JSONObject jsonObject = JSONObject.parseObject(send_standard);
        boolean success = (boolean) jsonObject.get("success");
        OperateOption option = OperateOption.create();
        if (success) { //成功，记录审批结果
            log.put("pdesc", "成功");
            FacadeHelper.apiLog(log);
            String data = (String) jsonObject.get("data");
            JSONObject jsonObject1 = JSONObject.parseObject(data);
            Object incident = jsonObject1.get("incident");
            if (incident != null) {
                String incident1 = incident.toString();
                er_publicReimburseBill.set("qeug_processinstance", incident1);
                OperationServiceHelper.executeOperate("save", "er_publicreimbursebill", new DynamicObject[]{er_publicReimburseBill}, option);
            }
        } else {//失败的情况
            //撤销提交，记录日志
            log.put("pdesc", "失败");
            FacadeHelper.apiLog(log);
            OperationServiceHelper.executeOperate("unsubmit", "er_publicreimbursebill", new DynamicObject[]{er_publicReimburseBill}, option);
            String error = jsonObject.getString("error");
            if (error != null) {
                throw new RuntimeException("提交至BPM失败，异常原因:" + error);
            } else {
                String data = (String) jsonObject.get("data");
                throw new RuntimeException("提交至BPM失败，异常原因:" + data);
            }
        }
    }

    //资金计划——月度支出计划/月度收入计划/周支出计划/周收入计划
    @Override
    public void billOrgTpl(DynamicObject bos_billOrgTpl) throws ServiceException, RemoteException, MalformedURLException {

        String bpmv2_url = System.getProperty("bpmv2.url");
        String basicAuthUserName = System.getProperty("bpmv2.user");//名字
        String basicAuthPassword = System.getProperty("bpmv2.password");//编码
        String returnUrl = System.getProperty("bpm.returnUrl");//URL地址

        //日志
        HashMap<String, Object> log = new HashMap<>();
        log.put("operationModule", "资金计划");
        log.put("url", bpmv2_url);
        log.put("user", basicAuthUserName);
        log.put("mode", "POST");
        log.put("action", "");
        log.put("opdate", new Date());
        BpmApplyInfo bpmApplyInfo = new BpmApplyInfo();
        ArrayList<ZjEntry> ZjEntrys = new ArrayList<>();//资金分录
        String billnumber = bos_billOrgTpl.getString("billno");//单据编码
        DynamicObject applier = bos_billOrgTpl.getDynamicObject("qeug_sqperson");//申请人
        if (applier != null) {
            String userNumber = applier.getString("number");
            String userName = applier.getString("name");
            bpmApplyInfo.setApplierNumber(userNumber);
            bpmApplyInfo.setApplierName(userName);
        }
        DynamicObject org = bos_billOrgTpl.getDynamicObject("qeug_costdept");//一级承担部门
        if (org != null) {
            String orgNumber = org.getString("number");
            String orgName = org.getString("name");
            bpmApplyInfo.setAdminOrgNumber(orgNumber);
            bpmApplyInfo.setAdminOrgName(orgName);
        }
        DynamicObject company = bos_billOrgTpl.getDynamicObject("org");//公司
        if (company != null) {
            String companyNumber = company.getString("number");
            String companyName = company.getString("name");
            bpmApplyInfo.setCompanyNumber(companyNumber);
            bpmApplyInfo.setCompanyName(companyName);
        }
        DynamicObject tripType = bos_billOrgTpl.getDynamicObject("qeug_billtype");//单据类型
        String tripTypeNumber = tripType.getString("number");
        String tripTypeName = tripType.getString("name");
        boolean istz = bos_billOrgTpl.getBoolean("qeug_istz");//是否调整
        if (tripTypeNumber.equals("qeug_fundplan_01") || tripTypeNumber.equals("qeug_fundplan_02") || tripTypeNumber.equals("qeug_fundadjust_01") || tripTypeNumber.equals("qeug_fundadjust_02")) {
            //月度支出和月度收入计划，资金计划调整的月度支出和月度收入计划
            Date yearmonth = bos_billOrgTpl.getDate("qeug_yearmonth");//年月
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
            String formattedYearMonth = sdf.format(yearmonth);
            bpmApplyInfo.setYearmonth(formattedYearMonth);
        } else if (tripTypeNumber.equals("qeug_fundplan_03") || tripTypeNumber.equals("qeug_fundplan_04")) {
            //周支出，周收入计划
            Date budgetDate = bos_billOrgTpl.getDate("qeug_ysdate");//预算日期
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String formattedBudgetDate = sdf.format(budgetDate);
            String BudgetWeekName = bos_billOrgTpl.getString("qeug_week1");//预算周

            bpmApplyInfo.setBudgetDate(formattedBudgetDate);
            bpmApplyInfo.setBudgetWeek(BudgetWeekName);
        }

        bpmApplyInfo.setBillnumber(billnumber);
        bpmApplyInfo.setBillType(tripTypeName);
        if (istz) {
            bpmApplyInfo.setIstz("是");
        } else {
            bpmApplyInfo.setIstz("否");
        }

        //资金分录
        DynamicObjectCollection fundsCollection = bos_billOrgTpl.getDynamicObjectCollection("entryentity");
        for (int i = 0; i < fundsCollection.size(); i++) {
            DynamicObject fundsEntry = fundsCollection.get(i);
            ZjEntry zjEntry = new ZjEntry();
            DynamicObject salesman = fundsEntry.getDynamicObject("qeug_person");//业务员
            if (salesman != null) {
                String salesmanName = salesman.getString("name");
                zjEntry.setSalesman(salesmanName);
            }
            DynamicObject collecting = fundsEntry.getDynamicObject("qeug_fundtype");//资金类别
            if (collecting != null) {
                String collectingName = collecting.getString("name");
                zjEntry.setCollecting(collectingName);
            }
            DynamicObject fundcate = fundsEntry.getDynamicObject("qeug_fundcate");//款项大类
            if (fundcate != null) {
                String fundcateName = fundcate.getString("name");
                zjEntry.setFundcate(fundcateName);
            }
            DynamicObject fundsuse = fundsEntry.getDynamicObject("qeug_fundsuse");//款项用途
            if (fundsuse != null) {
                String fundsuseName = fundsuse.getString("name");
                zjEntry.setFundsuse(fundsuseName);
            }
            DynamicObject currency = fundsEntry.getDynamicObject("qeug_currency");//币种
            if (currency != null) {
                String currencyName = currency.getString("name");
                zjEntry.setCurrency(currencyName);
            }
            String remark = fundsEntry.getString("qeug_remark");//说明
            if (istz) {
                //资金计划调整特有字段
                BigDecimal preBankDeposit = fundsEntry.getBigDecimal("qeug_bankamount");//调整前银行存款
                BigDecimal preAcceptanceBill = fundsEntry.getBigDecimal("qeug_hpamount"); // 调整前承兑汇票
                BigDecimal preLetterOfCredit = fundsEntry.getBigDecimal("qeug_xyzamount"); // 调整前信用证
                BigDecimal postBankDeposit = fundsEntry.getBigDecimal("qeug_newbankamount"); // 调整后银行存款
                BigDecimal postAcceptanceBill = fundsEntry.getBigDecimal("qeug_newyshpamount"); // 调整后承兑汇票
                BigDecimal postLetterOfCredit = fundsEntry.getBigDecimal("qeug_newxyzamount"); // 调整后信用证
                String upstreamID = fundsEntry.getString("qeug_sourceenid");//上游分录ID

                zjEntry.setPreBankDeposit(preBankDeposit);
                zjEntry.setPreAcceptanceBill(preAcceptanceBill);
                zjEntry.setPreLetterOfCredit(preLetterOfCredit);
                zjEntry.setPostBankDeposit(postBankDeposit);
                zjEntry.setPostAcceptanceBill(postAcceptanceBill);
                zjEntry.setPostLetterOfCredit(postLetterOfCredit);
                zjEntry.setUpstreamID(upstreamID);
                switch (tripTypeNumber) {
                    case "qeug_fundadjust_01": {
                        //月度支出计划
                        String paymentType = fundsEntry.getString("qeug_paytype");//付款类别
                        if ("1".equals(paymentType)) {
                            paymentType = "应付";
                        } else if ("2".equals(paymentType)) {
                            paymentType = "预付";
                        } else if ("3".equals(paymentType)) {
                            paymentType = "事项";
                        }
                        Date planDate = fundsEntry.getDate("qeug_planpaydate");//计划收付款日期
                        DynamicObject collectUnit = fundsEntry.getDynamicObject("qeug_supplier");//收款单位
                        if (collectUnit != null) {
                            String collectUnitName = collectUnit.getString("name");
                            zjEntry.setCollectUnit(collectUnitName);
                        }
                        String tzproject = fundsEntry.getString("qeug_tzproject");//投资项目
                        DynamicObject sffs = fundsEntry.getDynamicObject("qeug_sffs");//收付方式
                        if (sffs != null) {
                            String sffsName = sffs.getString("name");
                            zjEntry.setSffs(sffsName);
                        }
                        String contractnum = fundsEntry.getString("qeug_contractnum");//合同号

                        zjEntry.setPayType(paymentType);
                        zjEntry.setPlanDate(String.valueOf(planDate));
                        zjEntry.setTzproject(tzproject);
                        zjEntry.setContractnum(contractnum);
                        break;
                    }
                    case "qeug_fundadjust_02": {
                        //月度收入计划
                        Date planDate = fundsEntry.getDate("qeug_planpaydate");//计划收付款日期
                        DynamicObject customer = fundsEntry.getDynamicObject("qeug_customer");//客户
                        if (customer != null) {
                            String customerName = customer.getString("name");
                            zjEntry.setCustomer(customerName);
                        }
                        DynamicObject sffs = fundsEntry.getDynamicObject("qeug_sffs");//收付方式
                        if (sffs != null) {
                            String sffsName = sffs.getString("name");
                            zjEntry.setSffs(sffsName);
                        }

                        zjEntry.setPlanDate(String.valueOf(planDate));
                        break;
                    }
                }
            } else {
                //资金计划特有字段
                BigDecimal initBankDep = fundsEntry.getBigDecimal("qeug_ysbankamount");//初始银行存款
                BigDecimal initBill = fundsEntry.getBigDecimal("qeug_yshpamount");//初始承兑汇票
                BigDecimal initLC = fundsEntry.getBigDecimal("qeug_ysxyzamount");//初始信用证
                BigDecimal remainBankDep = fundsEntry.getBigDecimal("qeug_bankamount");//剩余银行存款
                BigDecimal remainBill = fundsEntry.getBigDecimal("qeug_hpamount");//剩余承兑汇票
                BigDecimal remainLC = fundsEntry.getBigDecimal("qeug_xyzamount");//剩余信用证
                BigDecimal totalDeductBankDep = fundsEntry.getBigDecimal("qeug_amountfield2");//累计扣减银行存款
                BigDecimal totalDeductBill = fundsEntry.getBigDecimal("qeug_amountfield1");//累计扣减承兑汇票
                BigDecimal totalDeductLC = fundsEntry.getBigDecimal("qeug_amountfield3");//累计扣减信用证

                zjEntry.setInitBankDep(initBankDep);
                zjEntry.setInitBill(initBill);
                zjEntry.setInitLC(initLC);
                zjEntry.setRemainBankDep(remainBankDep);
                zjEntry.setRemainBill(remainBill);
                zjEntry.setRemainLC(remainLC);
                zjEntry.setTotalDeductBankDep(totalDeductBankDep);
                zjEntry.setTotalDeductBill(totalDeductBill);
                zjEntry.setTotalDeductLC(totalDeductLC);
                switch (tripTypeNumber) {
                    case "qeug_fundplan_01": {
                        //月度支出计划
                        String paymentType = fundsEntry.getString("qeug_paytype");//付款类别
                        if ("1".equals(paymentType)) {
                            paymentType = "应付";
                        } else if ("2".equals(paymentType)) {
                            paymentType = "预付";
                        } else if ("3".equals(paymentType)) {
                            paymentType = "事项";
                        }
                        Date planDate = fundsEntry.getDate("qeug_planpaydate");//计划收付款日期
                        DynamicObject collectUnit = fundsEntry.getDynamicObject("qeug_supplier");//收款单位
                        if (collectUnit != null) {
                            String collectUnitName = collectUnit.getString("name");
                            zjEntry.setCollectUnit(collectUnitName);
                        }
                        String tzproject = fundsEntry.getString("qeug_tzproject");//投资项目
                        DynamicObject sffs = fundsEntry.getDynamicObject("qeug_sffs");//收付方式
                        if (sffs != null) {
                            String sffsName = sffs.getString("name");
                            zjEntry.setSffs(sffsName);
                        }
                        String contractnum = fundsEntry.getString("qeug_contractnum");//合同号

                        zjEntry.setPayType(paymentType);
                        zjEntry.setPlanDate(String.valueOf(planDate));
                        zjEntry.setTzproject(tzproject);
                        zjEntry.setContractnum(contractnum);
                        break;
                    }
                    case "qeug_fundplan_02": {
                        //月度收入计划
                        Date planDate = fundsEntry.getDate("qeug_planpaydate");//计划收付款日期
                        zjEntry.setPlanDate(String.valueOf(planDate));
                        DynamicObject customer = fundsEntry.getDynamicObject("qeug_customer");//客户
                        if (customer != null) {
                            String customerName = customer.getString("name");
                            zjEntry.setCustomer(customerName);
                        }
                        DynamicObject sffs = fundsEntry.getDynamicObject("qeug_sffs");//收付方式
                        if (sffs != null) {
                            String sffsName = sffs.getString("name");
                            zjEntry.setSffs(sffsName);
                        }
                        break;
                    }
                    case "qeug_fundplan_03": {
                        //周支出计划
                        String payrequsetnum = fundsEntry.getString("qeug_requestpaynum");//付款申请单号
                        zjEntry.setPayrequsetnum(payrequsetnum);
                        DynamicObject collectUnit = fundsEntry.getDynamicObject("qeug_supplier");//收款单位
                        if (collectUnit != null) {
                            String collectUnitName = collectUnit.getString("name");
                            zjEntry.setCollectUnit(collectUnitName);
                        }
                        DynamicObject bank = fundsEntry.getDynamicObject("qeug_bank");//收款银行
                        if (bank != null) {
                            String bankName = bank.getString("name");
                            zjEntry.setBank(bankName);
                        }
                        BigDecimal localamount = fundsEntry.getBigDecimal("qeug_localamount");//原币金额
                        zjEntry.setLocalamount(localamount);
                        break;
                    }
                    case "qeug_fundplan_04": {
                        //周收入计划
                        String payrequsetnum = fundsEntry.getString("qeug_requestpaynum");//付款申请单号
                        zjEntry.setPayrequsetnum(payrequsetnum);
                        DynamicObject customer = fundsEntry.getDynamicObject("qeug_customer");//客户
                        if (customer != null) {
                            String customerName = customer.getString("name");
                            zjEntry.setCustomer(customerName);
                        }
                        BigDecimal localamount = fundsEntry.getBigDecimal("qeug_localamount");//原币金额
                        zjEntry.setLocalamount(localamount);
                        break;
                    }
                }
            }

            zjEntry.setRemark(remark);

            ZjEntrys.add(zjEntry);
        }
        //附件分录
        long billId = bos_billOrgTpl.getLong("id");
        String domain = System.getProperty("domain.contextUrl");
        List tripReimburse = null;
        if (istz) {
            tripReimburse = AttachmentServiceFactory.getServiceInstance(CheckMethodEnum.CUSTOM).queryAttachmentInfo(billId, "qeug_fundadjust", false);//资金计划调整
        } else {
            tripReimburse = AttachmentServiceFactory.getServiceInstance(CheckMethodEnum.CUSTOM).queryAttachmentInfo(billId, "qeug_fundplan", false);//资金计划
        }
        List<Attentrys> attEntrys = new ArrayList<Attentrys>();
        if (tripReimburse != null) {
            for (Object attachment : tripReimburse) {
                Attentrys attEntry = new Attentrys();
                Attachment bos_attachment = (Attachment) attachment;
                String url = bos_attachment.getUrl();
                String attUrl = domain + "/accessTokenLogin.do?access_token={}&redirect=" + url;//附件地址
                String fileName = bos_attachment.getFileName();//附件名称
                String attType = bos_attachment.getFileType();//附件类型

                attEntry.setAttUrl(attUrl);
                attEntry.setAttName(fileName);
                attEntry.setAttType(attType);

                attEntrys.add(attEntry);
            }
        }

        //人员信息
        DynamicObject creator = bos_billOrgTpl.getDynamicObject("creator");//创建人
        String creatorNumber = creator.getString("number");

        String strProcessName = "CCSZiJinJHSQ";

        String summaryV2 = BPMUtil.getSummaryV2(bos_billOrgTpl);

        String combinedString = "94893e8a64a2444d8cd41237e6a8bd56" + bos_billOrgTpl.getString("billno");
        String signature = DigestUtils.md5Hex(combinedString);
        String shortSignature = signature.substring(8, 24);

        //拼接Json
        bpmApplyInfo.setAttentrys(attEntrys);
        bpmApplyInfo.setZjEntry(ZjEntrys);

        bpmApplyInfo.setSysName("CCS");
        bpmApplyInfo.setDataId(bos_billOrgTpl.getString("billno"));
        bpmApplyInfo.setDataVersion("");//为空
        bpmApplyInfo.setSignature(shortSignature);
        bpmApplyInfo.setProcessName(strProcessName);
        bpmApplyInfo.setInitiatorName(creatorNumber);
        bpmApplyInfo.setReturnUrl(returnUrl);
        bpmApplyInfo.setFormUrl("");//为空
        bpmApplyInfo.setTitle(summaryV2);

        String json = JSONObject.toJSONString(bpmApplyInfo);

        String access_token = getAccessToken(bpmv2_url, basicAuthUserName, basicAuthPassword);
        String send_standard = HttpRequest.post(bpmv2_url + "/hitf/v2p/rest/invoke/SFpFUk86QlBNOkJQTV9TREsz")
                .header("Authorization", access_token)
                .body(json).execute().body();
        log.put("mainstring", json);
        log.put("responsebody", send_standard);
        logger.info("资金计划bpm回传信息：" + send_standard);

        JSONObject jsonObject = JSONObject.parseObject(send_standard);
        boolean success = (boolean) jsonObject.get("success");
        OperateOption option = OperateOption.create();
        if (success) { //成功，记录审批结果
            log.put("pdesc", "成功");
            FacadeHelper.apiLog(log);
            String data = (String) jsonObject.get("data");
            JSONObject jsonObject1 = JSONObject.parseObject(data);
            Object incident = jsonObject1.get("incident");
            if (incident != null) {
                String incident1 = incident.toString();
                bos_billOrgTpl.set("qeug_processinstance", incident1);
                OperationServiceHelper.executeOperate("save", "qeug_fundplan", new DynamicObject[]{bos_billOrgTpl}, option);
            }
        } else {//失败的情况
            //撤销提交，记录日志
            log.put("pdesc", "失败");
            FacadeHelper.apiLog(log);
            OperationServiceHelper.executeOperate("unsubmit", "qeug_fundplan", new DynamicObject[]{bos_billOrgTpl}, option);
            String error = jsonObject.getString("error");
            if (error != null) {
                throw new RuntimeException("提交至BPM失败，异常原因:" + error);
            } else {
                String data = (String) jsonObject.get("data");
                throw new RuntimeException("提交至BPM失败，异常原因:" + data);
            }
        }
    }

    //借款单
    @Override
    public void dailyLoanBill(DynamicObject er_dailyLoanBill) throws ServiceException, RemoteException, MalformedURLException {
        String bpmv2_url = System.getProperty("bpmv2.url");
        String basicAuthUserName = System.getProperty("bpmv2.user");//名字
        String basicAuthPassword = System.getProperty("bpmv2.password");//编码
        String returnUrl = System.getProperty("bpm.returnUrl");//URL地址
        String domain = System.getProperty("domain.contextUrl");//IP地址

        //日志
        HashMap<String, Object> log = new HashMap<>();
        log.put("operationModule", "借款单");
        log.put("url", bpmv2_url);
        log.put("user", basicAuthUserName);
        log.put("mode", "POST");
        log.put("action", "");
        log.put("opdate", new Date());
        BpmApplyInfo bpmApplyInfo = new BpmApplyInfo();
        ArrayList<FyEntry> fyEntrys = new ArrayList<>();//费用分录
        ArrayList<SkEntry> skEntrys = new ArrayList<>();//收款分录
        List<Attentrys> attEntrys = new ArrayList<Attentrys>();//附件分录
        DynamicObject applier = er_dailyLoanBill.getDynamicObject("applier");//申请人
        if (applier != null) {
            String userNumber = applier.getString("number");
            String userName = applier.getString("name");
            bpmApplyInfo.setApplierNumber(userNumber);
            bpmApplyInfo.setApplierName(userName);
        }
        DynamicObject org = er_dailyLoanBill.getDynamicObject("org");//申请部门
        if (org != null) {
            String orgNumber = org.getString("number");
            String orgName = org.getString("name");
            bpmApplyInfo.setAdminOrgNumber(orgNumber);
            bpmApplyInfo.setAdminOrgName(orgName);
        }
        DynamicObject company = er_dailyLoanBill.getDynamicObject("company");//申请公司
        if (company != null) {
            String companyNumber = company.getString("number");
            String companyName = company.getString("name");
            bpmApplyInfo.setCompanyNumber(companyNumber);
            bpmApplyInfo.setCompanyName(companyName);
        }
        Date applyDate = er_dailyLoanBill.getDate("bizdate");//申请日期
        DynamicObject costDept = er_dailyLoanBill.getDynamicObject("costdept");//费用承担部门
        if (costDept != null) {
            String costDeptNumber = costDept.getString("number");
            String costDeptName = costDept.getString("name");
            bpmApplyInfo.setExpenseDeptCode(costDeptNumber);
            bpmApplyInfo.setExpenseDeptName(costDeptName);
        }
        DynamicObject costCompany = er_dailyLoanBill.getDynamicObject("costcompany");//费用承担公司
        if (costCompany != null) {
            String costCompanyNumber = costCompany.getString("number");
            String costCompanyName = costCompany.getString("name");
            bpmApplyInfo.setCostBearingCode(costCompanyNumber);
            bpmApplyInfo.setCostBearingName(costCompanyName);
        }
        boolean isCurrency = er_dailyLoanBill.getBoolean("iscurrency");//多币别
        if (isCurrency) {
            bpmApplyInfo.setisCurrency("是");
        } else {
            bpmApplyInfo.setisCurrency("否");
        }
        String paymentType = er_dailyLoanBill.getString("qeug_paytype");//付款类别
        if ("1".equals(paymentType)) {
            paymentType = "应付";
        } else if ("2".equals(paymentType)) {
            paymentType = "预付";
        } else if ("3".equals(paymentType)) {
            paymentType = "事项";
        }
        String budgetType = er_dailyLoanBill.getString("qeug_budgetflag");//预算类型
        if ("0".equals(budgetType)) {
            budgetType = "预算外";
        } else if ("1".equals(budgetType)) {
            budgetType = "预算内";
        }
        bpmApplyInfo.setIsCyu(budgetType);
        String qeug_combofield = er_dailyLoanBill.getString("qeug_combofield");//标准内外
        if ("0".equals(qeug_combofield)) {
            qeug_combofield = "标准外";
        } else if ("1".equals(qeug_combofield)) {
            qeug_combofield = "标准内";
        }
        bpmApplyInfo.setIsCb(qeug_combofield);
        DynamicObject paymentPurpose = er_dailyLoanBill.getDynamicObject("qeug_kmname");//款项用途
        if (paymentPurpose != null) {
            String paymentPurposeName = paymentPurpose.getString("name");
            bpmApplyInfo.setPaymentPurpose(paymentPurposeName);
        }
        DynamicObject approvalCategory = er_dailyLoanBill.getDynamicObject("qeug_approvaltype");//审批类别
        if (approvalCategory != null) {
            String approvalCategoryName = approvalCategory.getString("name");
            bpmApplyInfo.setApprovalCategory(approvalCategoryName);
            String approvalCategoryDesc = er_dailyLoanBill.getString("qeug_descriptions");//审批类别-具体描述
            String approvalCategoryProject = er_dailyLoanBill.getString("qeug_project");//审批类别-项目
            bpmApplyInfo.setApprovalCategoryDesc(approvalCategoryDesc);
            bpmApplyInfo.setApprovalCategoryProject(approvalCategoryProject);
        }
        String insideCause = er_dailyLoanBill.getString("description");//事由（内）
        BigDecimal loanamount = er_dailyLoanBill.getBigDecimal("loanamount");//借款金额

        bpmApplyInfo.setBillType("借款单");
        bpmApplyInfo.setBizdate(String.valueOf(applyDate));
        bpmApplyInfo.setPaymentCategory(paymentType);
        bpmApplyInfo.setReason(insideCause);
        bpmApplyInfo.setAmountPayable(loanamount);//应付金额
        bpmApplyInfo.setDeductionAmount(BigDecimal.ZERO);//扣款金额

        //借款明细
        DynamicObjectCollection expenselCollection = er_dailyLoanBill.getDynamicObjectCollection("expenseentryentity");
        for (int j = 0; j < expenselCollection.size(); j++) {
            DynamicObject expenseEntry = expenselCollection.get(j);
            FyEntry fyEntry = new FyEntry();
            DynamicObject entryCostDept = expenseEntry.getDynamicObject("entrycostdept");//费用承担部门
            if (entryCostDept != null) {
                String entryCostDeptName = entryCostDept.getString("name");
                fyEntry.setExpenseDeptName(entryCostDeptName);
            }
            DynamicObject expenseType = expenseEntry.getDynamicObject("qeug_expensetype");//费用类型
            if (expenseType != null) {
                String expenseTypeName = expenseType.getString("fullname");
                fyEntry.setExpenseType(expenseTypeName);
            }
            DynamicObject expenseDetail = expenseEntry.getDynamicObject("qeug_expensedetail");//费用细项
            if (expenseDetail != null) {
                String expenseDetailName = expenseDetail.getString("fullname");
                fyEntry.setExpenseDetail(expenseDetailName);
            }
            DynamicObject expenseItem = expenseEntry.getDynamicObject("expenseitem");//费用名目（长名称，编码
            if (expenseItem != null) {
                String expenseItemName = expenseItem.getString("fullname");
                String expenseItemNumber = expenseItem.getString("number");
                fyEntry.setExpenseItemName(expenseItemName);
                fyEntry.setExpenseItemNumber(expenseItemNumber);
            }
            BigDecimal amount = expenseEntry.getBigDecimal("expenseamount");//借款金额
            if (isCurrency) {
                DynamicObject entryCurrency = expenseEntry.getDynamicObject("entrycurrency");//币别
                String entryCurrencyName = entryCurrency.getString("name");
                fyEntry.setEntryCurrency(entryCurrencyName);
            } else {
                fyEntry.setEntryCurrency("人民币");//多币别关闭时推送人民币
            }
            String exchanGerate = expenseEntry.getString("exchangerate");//汇率
            if (exchanGerate != null) {
                String exchanGerates = String.format("%.2f", Double.parseDouble(exchanGerate));
                fyEntry.setExchanGerate(exchanGerates);
            }
            BigDecimal amountRaw = expenseEntry.getBigDecimal("currexpenseamount");//借款金额（本位币）

            fyEntry.setAmountRaw(amountRaw);
            fyEntry.setAmount(amount);
            fyEntrys.add(fyEntry);
        }
        //收款页签
        DynamicObjectCollection receiptCollection = er_dailyLoanBill.getDynamicObjectCollection("accountentry");
        for (int i = 0; i < receiptCollection.size(); i++) {
            DynamicObject receiptEntry = receiptCollection.get(i);
            SkEntry skEntry = new SkEntry();
            DynamicObject paymode = receiptEntry.getDynamicObject("paymode");//支付方式
            if (paymode != null) {
                String paymodeName = paymode.getString("name");
                String paymodeNumber = paymode.getString("number");
                skEntry.setPayTpye(paymodeName);
                skEntry.setPayTpyeNumber(paymodeNumber);
            }
            String payerType = receiptEntry.getString("payertype");//收款人类型
            if ("bd_supplier".equals(payerType)) {
                skEntry.setRecipientType("供应商");
            } else if ("bd_customer".equals(payerType)) {
                skEntry.setRecipientType("客户");
            } else if ("bos_org".equals(payerType)) {
                skEntry.setRecipientType("内部公司");
            } else if ("er_payeer".equals(payerType)) {
                skEntry.setRecipientType("个人");
            } else if ("other".equals(payerType)) {
                skEntry.setRecipientType("其他");
            }
            String payertype = receiptEntry.getString("payertype");//收款人类型
            if (payertype.equals("bd_supplier")) {
                //收款人类型为供应商
                DynamicObject payee = receiptEntry.getDynamicObject("supplier");//收款人-供应商
                if (payee != null) {
                    String payeeName = payee.getString("name");
                    String payeeNumber = payee.getString("number");
                    skEntry.setPayeeName(payeeName);
                    skEntry.setPayeeNumber(payeeNumber);
                }
            } else {
                //收款人类型为人员
                DynamicObject payee = receiptEntry.getDynamicObject("payer");//收款人-人员
                if (payee != null) {
                    String payeeName = payee.getString("name");
                    String payeeNumber = payee.getString("payer.number");
                    skEntry.setPayeeName(payeeName);
                    skEntry.setPayeeNumber(payeeNumber);
                }
            }
            String payeeAccount = receiptEntry.getString("payeraccount");//银行账号
            String correspondentNumber = receiptEntry.getString("qeug_union");//联行号
            String accountTitle = receiptEntry.getString("payeraccountname");//账户名称
            DynamicObject openBankAccount = receiptEntry.getDynamicObject("payerbank");//开户银行
            if (openBankAccount != null) {
                String openBankAccountName = openBankAccount.getString("name");
                String openBankAccountNumber = openBankAccount.getString("number");
                skEntry.setBankName(openBankAccountName);
                skEntry.setBankNumber(openBankAccountNumber);
            }
            BigDecimal receiveAmount = receiptEntry.getBigDecimal("orireceiveamount");//收款金额
            if (isCurrency) {
                DynamicObject entryCurrency = receiptEntry.getDynamicObject("accountcurrency");//币别
                String entryCurrencyName = entryCurrency.getString("name");
                skEntry.setEntryCurrency(entryCurrencyName);
            } else {
                skEntry.setEntryCurrency("人民币");//多币别关闭时推送人民币
            }

            String exchanGerate = receiptEntry.getString("accexchangerate");//汇率
            if (exchanGerate != null) {
                String exchanGerates = String.format("%.2f", Double.parseDouble(exchanGerate));
                skEntry.setExchanGerate(exchanGerates);
            }
            BigDecimal attachmentsRaw = receiptEntry.getBigDecimal("receiveamount");//收款金额（本位币）

            skEntry.setAttachmentsRaw(attachmentsRaw);
            skEntry.setBankNum(payeeAccount);
            skEntry.setAccountTitle(accountTitle);
            skEntry.setInterbank(correspondentNumber);
            skEntry.setAttachments(receiveAmount);

            skEntrys.add(skEntry);
        }
        //附件分录
        long billId = er_dailyLoanBill.getLong("id");
        List tripReimburse = AttachmentServiceFactory.getServiceInstance(CheckMethodEnum.CUSTOM).queryAttachmentInfo(billId, "er_dailyloanbill", false);//借款单
        for (Object attachment : tripReimburse) {
            Attentrys attEntry = new Attentrys();
            Attachment bos_attachment = (Attachment) attachment;
            String url = bos_attachment.getUrl();
            String attUrl = domain + "/accessTokenLogin.do?access_token={}&redirect=" + url;//附件地址
            String fileName = bos_attachment.getFileName();//附件名称
            String attType = bos_attachment.getFileType();//附件类型

            attEntry.setAttUrl(attUrl);
            attEntry.setAttName(fileName);
            attEntry.setAttType(attType);

            attEntrys.add(attEntry);
        }

        //人员信息
        DynamicObject creator = er_dailyLoanBill.getDynamicObject("creator");//创建人
        String creatorNumber = creator.getString("number");

        String strProcessName = "CCSFuKuanSQ";

        String summaryV2 = BPMUtil.getSummaryV2(er_dailyLoanBill);

        String combinedString = "94893e8a64a2444d8cd41237e6a8bd56" + er_dailyLoanBill.getString("billno");
        String signature = DigestUtils.md5Hex(combinedString);
        String shortSignature = signature.substring(8, 24);

        //拼接Json
        bpmApplyInfo.setAttentrys(attEntrys);
        bpmApplyInfo.setFyEntry(fyEntrys);
        bpmApplyInfo.setSkEntry(skEntrys);

        bpmApplyInfo.setSysName("CCS");
        bpmApplyInfo.setDataId(er_dailyLoanBill.getString("billno"));
        bpmApplyInfo.setDataVersion("");//为空
        bpmApplyInfo.setSignature(shortSignature);
        bpmApplyInfo.setProcessName(strProcessName);
        bpmApplyInfo.setInitiatorName(creatorNumber);
        bpmApplyInfo.setReturnUrl(returnUrl);
        bpmApplyInfo.setFormUrl("");//为空
        bpmApplyInfo.setTitle(summaryV2);

        String json = JSONObject.toJSONString(bpmApplyInfo);

        String access_token = getAccessToken(bpmv2_url, basicAuthUserName, basicAuthPassword);
        String send_standard = HttpRequest.post(bpmv2_url + "/hitf/v2p/rest/invoke/SFpFUk86QlBNOkJQTV9TREsz")
                .header("Authorization", access_token)
                .body(json).execute().body();

        log.put("mainstring", json);
        log.put("responsebody", send_standard);
        logger.info("借款单bpm回传信息：" + send_standard);

        JSONObject jsonObject = JSONObject.parseObject(send_standard);
        boolean success = (boolean) jsonObject.get("success");
        OperateOption option = OperateOption.create();
        if (success) { //成功，记录审批结果
            log.put("pdesc", "成功");
            FacadeHelper.apiLog(log);
            String data = (String) jsonObject.get("data");
            JSONObject jsonObject1 = JSONObject.parseObject(data);
            Object incident = jsonObject1.get("incident");
            if (incident != null) {
                String incident1 = incident.toString();
                er_dailyLoanBill.set("qeug_processinstance", incident1);
                OperationServiceHelper.executeOperate("save", "er_publicreimbursebill", new DynamicObject[]{er_dailyLoanBill}, option);
            }
        } else {//失败的情况
            //撤销提交，记录日志
            log.put("pdesc", "失败");
            FacadeHelper.apiLog(log);
            OperationServiceHelper.executeOperate("unsubmit", "er_publicreimbursebill", new DynamicObject[]{er_dailyLoanBill}, option);
            String error = jsonObject.getString("error");
            if (error != null) {
                throw new RuntimeException("提交至BPM失败，异常原因:" + error);
            } else {
                String data = (String) jsonObject.get("data");
                throw new RuntimeException("提交至BPM失败，异常原因:" + data);
            }
        }
    }

    //获取access_token
    public static String getAccessToken(String bpmv2_url, String basicAuthUserName, String basicAuthPassword) {
        String access_token = null;
        try {
            URL obj = new URL(bpmv2_url + "/oauth/oauth/token");
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

            con.setDoOutput(true);

            String urlParameters = "client_id=" + basicAuthUserName + "&client_secret=" + basicAuthPassword + "&grant_type=client_credentials";
            OutputStream os = con.getOutputStream();
            os.write(urlParameters.getBytes());
            os.flush();
            os.close();

            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuilder response = new StringBuilder();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
            JSONObject jsonObject2 = JSONObject.parseObject(String.valueOf(response));
            access_token = jsonObject2.getString("access_token");

        } catch (Exception e) {
            e.printStackTrace();
        }
        return access_token;
    }
}
